package user

import (
	"cgs-server/helper"
	"cgs-server/server"
	"cgs-server/server/base"
	"cgs-server/server/model"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

func init() {
	//server.Handle(http.MethodPost, "/api/User/Add", AddUser, server.Administrator)
	//server.Handle(http.MethodPost, "/api/User/ChangePassword", ChangePassword2, server.Login)
	//server.Handle(http.MethodPost, "/api/User/Edit", EditUser, server.Administrator)
	//server.Handle(http.MethodGet, "/api/User/List", ListUser, server.Administrator)
	//server.Handle(http.MethodGet, "/api/User/GetUserByIdOrName", GetUserByIdOrUserName, server.Login)
	//server.Handle(http.MethodPost, "/api/User/Delete", DeleteUser, server.Administrator)

	server.Post("/api/User/Add", AddUser, "添加用户", server.ManageBackend)
	server.Post("/api/User/ChangePassword", ChangePassword2, "修改密码", server.Login)
	server.Post("/api/User/ResetPassword", ResetPassword, "重置密码", server.Login)
	server.Post("/api/User/RetrievePassword", RetrievePassword, "找回密码", server.None)
	server.Post("/api/User/Edit", EditUser, "更新用户", server.ManageBackend)
	server.Get("/api/User/List", ListUser, "获取用户列表", server.Login)
	server.Get("/api/User/ListOfDept", ListDeptUser, "获取部门用户列表", server.Login)
	server.Get("/api/User/GetUserByIdOrName", GetUserByIdOrUserName, "获取用户", server.Login)
	server.Post("/api/User/Delete", DeleteUser, "删除用户", server.ManageBackend)
	server.Get("/api/User/Info", GetUserInfo, "获取用户信息", server.Login)
	server.Get("/api/User/CheckByUsername", CheckByUsername, "获取用户", server.None)
	server.Get("/api/User/getAppAuth", getAppAuth, "获取用户拥有的某个应用的权限", server.Login)
	server.Get("/api/v2/User/getAppAuth", getAppAuth2, "获取用户拥有的某个应用的权限", server.Login)
}

func AddUser(w http.ResponseWriter, r *http.Request) {
	r.Body = http.MaxBytesReader(w, r.Body, int64(100<<20))
	s, _ := ioutil.ReadAll(r.Body)
	userData := &model.User{}
	err := helper.FromJSON(s, userData)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	if userData.Username == "" || userData.Password == "" || userData.Name == "" {
		_, _ = helper.WriteJSON(w, server.Fail("Field of username, password, name is not allowed to be empty."))
		return
	}
	err = userData.ValidatePhoneQQEmail()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	salt := helper.TimeToString(time.Now(), "yyyyMMddHHmmss")
	userData.Pwd = helper.MD5(userData.Password + salt)
	userData.Salt = salt

	dataUserModel := base.GenerateDataUserModel(userData, r)

	userService := NewUserService()
	err = userService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = userService.Save(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	_, _ = helper.WriteJSON(w, server.OK().WithData(bson.M{
		"userId": userData.UserId,
	}))

}

func ChangePassword2(w http.ResponseWriter, r *http.Request) {
	oldPassword := strings.TrimSpace(r.FormValue("oldPassword"))
	newPassword := strings.TrimSpace(r.FormValue("newPassword"))
	confirmPassword := strings.TrimSpace(r.FormValue("confirmPassword"))

	if oldPassword == "" || newPassword == "" || confirmPassword == "" {
		_, _ = helper.WriteJSON(w, server.Fail("All password fields are not allowed to be empty."))
		return
	}
	if newPassword != confirmPassword {
		_, _ = helper.WriteJSON(w, server.Fail("New password and confirm password is not the same."))
		return
	}

	changeModel := &model.ChangeUserPasswordModel{
		OldPassword:     oldPassword,
		NewPassword:     newPassword,
		ConfirmPassword: confirmPassword,
	}
	dataUserModel := base.GenerateDataUserModel(changeModel, r)
	if dataUserModel.User == nil {
		_, _ = helper.WriteJSON(w, server.Fail("The user is not exist."))
		return
	}

	changeModel.SetId(dataUserModel.User.UserId)

	userService := NewUserService()
	err := userService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = userService.ChangePassword(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	_, _ = helper.WriteJSON(w, server.OK("Change password successfully!"))
}

func ResetPassword(w http.ResponseWriter, r *http.Request) {
	newPassword := strings.TrimSpace(r.FormValue("newPassword"))
	confirmPassword := strings.TrimSpace(r.FormValue("confirmPassword"))
	if newPassword == "" {
		_, _ = helper.WriteJSON(w, server.Fail("New password and confirm password is required."))
		return
	}
	if newPassword != confirmPassword {
		_, _ = helper.WriteJSON(w, server.Fail("New password and confirm password is not the same."))
		return
	}
	userId, err := primitive.ObjectIDFromHex(r.FormValue("userId"))
	if err != nil {
		helper.WriteJSON(w, server.Fail("user id is empty"))
		return
	}
	changeModel := &model.ChangeUserPasswordModel{
		NewPassword:     newPassword,
		ConfirmPassword: confirmPassword,
	}
	changeModel.UserId = userId
	dataUserModel := base.GenerateDataUserModel(changeModel, r)
	if dataUserModel.User == nil {
		_, _ = helper.WriteJSON(w, server.Fail("The user is not exist."))
		return
	}
	userService := NewUserService()
	err = userService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = userService.ResetPassword(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	_, _ = helper.WriteJSON(w, server.OK("Change password successfully!"))
}

// 找回密码
func RetrievePassword(w http.ResponseWriter, r *http.Request) {
	changeModel := &model.ChangeUserPasswordModel{}
	if err := helper.ReadRequestBody(changeModel, w, r); err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if err := helper.GetValidator().Struct(changeModel); err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if !helper.CheckPhone(changeModel.PhoneNumber) {
		_, _ = helper.WriteJSON(w, server.Fail("手机号格式不正确"))
		return
	}
	dataUserModel := base.GenerateDataUserModel(changeModel, r)
	if dataUserModel.User == nil {
		_, _ = helper.WriteJSON(w, server.Fail("The user is not exist."))
		return
	}
	userService := NewUserService()
	err := userService.RetrievePassword(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	_, _ = helper.WriteJSON(w, server.OK("Retrieve password successfully!"))
}

func EditUser(w http.ResponseWriter, r *http.Request) {
	r.Body = http.MaxBytesReader(w, r.Body, int64(100<<20))
	s, _ := ioutil.ReadAll(r.Body)
	userData := &model.User{}
	err := helper.FromJSON(s, userData)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if userData.UserId.IsZero() && userData.Username == "" {
		_, _ = helper.WriteJSON(w, server.Fail("userId or usrname is required."))
		return
	}

	err = userData.ValidatePhoneQQEmail()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	dataUserModel := base.GenerateDataUserModel(userData, r)
	if dataUserModel.User == nil {
		_, _ = helper.WriteJSON(w, server.Fail("The user is not exist."))
		return
	}

	// service
	userService := NewUserService()
	err = userService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = userService.Update(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	_, _ = helper.WriteJSON(w, server.OK("Update successfully!"))
}

func ListUser(w http.ResponseWriter, r *http.Request) {
	userService := NewUserService()
	err := userService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	duModel := base.GenerateDataUserModel(&model.User{}, r)
	result, err := userService.List(duModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	_, _ = helper.WriteJSON(w, server.OK().WithData(result))

}
func ListDeptUser(w http.ResponseWriter, r *http.Request) {
	userService := NewUserService()
	err := userService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	deptId := r.FormValue("deptId")
	duModel := base.GenerateDataUserModel(&model.User{}, r)
	result, err := userService.ListDept(duModel, deptId)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	_, _ = helper.WriteJSON(w, server.OK().WithData(result))
}
func GetUserByIdOrUserName(w http.ResponseWriter, r *http.Request) {
	user := &model.User{}
	id := r.FormValue("userId")
	username := r.FormValue("username")
	if id == "" && username == "" {
		_, _ = helper.WriteJSON(w, server.Fail("UserId or username is required."))
		return
	}
	if id != "" {
		userId, err := primitive.ObjectIDFromHex(id)
		if err != nil {
			_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
			return
		}
		user.UserId = userId
	}
	user.Username = username

	userService := NewUserService()
	err := userService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	duModel := base.GenerateDataUserModel(user, r)
	result, err := userService.GetByUserIdOrUserName(duModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(result))
}

func DeleteUser(w http.ResponseWriter, r *http.Request) {
	userData := &model.User{}
	userId, err := primitive.ObjectIDFromHex(r.FormValue("userId"))
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	userData.UserId = userId
	// service
	userService := NewUserService()
	err = userService.Init()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	duModel := base.GenerateDataUserModel(userData, r)
	err = userService.RemoveLogic(duModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Delete successfully!"))
}

func getAppAuth(w http.ResponseWriter, r *http.Request) {
	currentUser, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	visualId := r.FormValue("visualId")
	if visualId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("visualId is required"))
		return
	}

	// 查询用户信息
	userService := NewUserService()
	result, err := userService.GetAppAuth(visualId, currentUser)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Get successfully!").WithData(result))
}

func getAppAuth2(w http.ResponseWriter, r *http.Request) {
	currentUser, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	visualId := r.FormValue("visualId")
	if visualId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("visualId is required"))
		return
	}

	// 查询用户信息
	userService := NewUserService()
	result, err := userService.GetAppAuth2(visualId, currentUser)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Get successfully!").WithData(result))
}

func GetUserInfo(w http.ResponseWriter, r *http.Request) {
	currentUser, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	// 查询用户信息
	userService := NewUserService()
	//duModel := base.GenerateDataUserModel(currentUser, r)
	duModel := &model.DataUserModel{
		Data: currentUser,
		User: currentUser,
	}
	result, err := userService.GetByUserIdOrUserName(duModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Get successfully!").WithData(result))
}

func CheckByUsername(w http.ResponseWriter, r *http.Request) {
	user := &model.User{}
	username := r.FormValue("username")
	if username == "" {
		_, _ = helper.WriteJSON(w, server.Fail("username is required."))
		return
	}
	user.Username = username

	userService := NewUserService()
	duModel := base.GenerateDataUserModel(user, r)
	result, _ := userService.FindByUsername(duModel)
	if result == nil {
		_, _ = helper.WriteJSON(w, server.OK().WithData(bson.M{
			"isExist": false,
		}))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(bson.M{
		"isExist": true,
	}))
}
